﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using HML.Design;

namespace HML
{
    /// <summary>
    /// 不规则形状按钮
    /// </summary>
    [Description("不规则形状按钮")]
    [DefaultProperty("ShapeEditorEnable")]
    [DefaultEvent("Click")]
    [TypeConverter(typeof(AnomalyButtonOrdinaryPropertyConverter))]
    [Designer(typeof(AnomalyButtonDesigner))]
    [PropertyTabAttribute(typeof(AnomalyButtonDesignerPropertyTab), PropertyTabScope.Component)]
    [ToolboxItem(true)]
    [ToolboxBitmap(typeof(AnomalyButton), "Controls.AnomalyButton.Resources.AnomalyButton.bmp")]
    public class AnomalyButton : DpiControl, ISkinObject
    {
        #region 主题

        private SkinObjectXmlMetadata skinObjectXmlMetadata = null;
        /// <summary>
        /// 主题对象在主题文件信息
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual SkinObjectXmlMetadata SkinObjectXmlMetadata
        {
            get
            {
                if (this.skinObjectXmlMetadata == null)
                    this.skinObjectXmlMetadata = new SkinObjectXmlMetadata(Assembly.GetAssembly(typeof(AnomalyButton)).GetName().Name, typeof(AnomalyButton).Name);

                return this.skinObjectXmlMetadata;
            }
        }

        private SkinController skinController = null;
        /// <summary>
        /// 主题控制器
        /// </summary>
        [Description("主题控制器")]
        [Category("杂项")]
        [PropertyOrder(-360)]
        [DefaultValue(null)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinController SkinController
        {
            get { return this.skinController; }
            set
            {
                if (this.skinController == value)
                    return;

                if (this.skinController != null)
                    this.skinController.RemoveSkinObject(this);

                this.skinController = value;

                if (this.skinController != null)
                    this.skinController.AddSkinObject(this);
            }
        }

        private SkinEnabledState skinEnabled = SkinEnabledState.Auto;
        /// <summary>
        /// 主题是否启用
        /// </summary>
        [Description("主题是否启用")]
        [Category("杂项")]
        [PropertyOrder(-300)]
        [DefaultValue(SkinEnabledState.Auto)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinEnabledState SkinEnabled
        {
            get { return this.skinEnabled; }
            set
            {
                if (this.skinEnabled == value)
                    return;

                this.skinEnabled = value;
                this.OnSkinChanged();
            }
        }

        private SkinStyle skinStyle = SkinStyle.Normal;
        /// <summary>
        /// 主题风格
        /// </summary>
        [Description("主题风格")]
        [Category("杂项")]
        [PropertyOrder(-260)]
        [DefaultValue(SkinStyle.Normal)]
        [RefreshProperties(RefreshProperties.All)]
        public virtual SkinStyle SkinStyle
        {
            get { return this.skinStyle; }
            set
            {
                if (this.skinStyle == value)
                    return;

                this.skinStyle = value;
                this.OnSkinChanged();
            }
        }

        private StyleAppearanceObject stateAppearance;
        /// <summary>
        /// 风格外观
        /// </summary>
        [Description("风格外观")]
        [Category("杂项")]
        [PropertyOrder(-200)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StyleAppearanceObject StyleAppearance
        {
            get
            {
                if (this.stateAppearance == null)
                    this.stateAppearance = new StyleAppearanceObject(this, null);
                return this.stateAppearance;
            }
        }

        /// <summary>
        /// 主题已更改
        /// </summary>
        public virtual void OnSkinChanged()
        {
            SkinManager.SyncSkinValueToProperty(this);
            this.Invalidate();
        }

        private ISkinObject followSkinObject = null;
        /// <summary>
        /// 主题设置跟随指定主题对象（自己的设置不再生效，提供给代码使用）
        /// </summary>
        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [Localizable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual ISkinObject FollowSkinObject
        {
            get { return this.followSkinObject; }
            set
            {
                if (this.followSkinObject == value)
                    return;

                this.followSkinObject = value;
                this.OnSkinChanged();
            }
        }

        public virtual bool GetSkinObjectSkinStateCore()
        {
            return SkinManager.GetSkinObjectSkinState(this.FollowSkinObject ?? this);
        }

        void ISkinObject.InitializeInvalidate()
        {
            this.InitializeElement();
            this.Invalidate();
        }

        void ISkinObject.Invalidate()
        {
            this.Invalidate();
        }

        #endregion

        #region 新增事件

        private static readonly object EventCheckedChanged = new object();
        /// <summary>
        /// 控件Checked状态更改事件
        /// </summary>
        [Description("控件Checked状态更改事件")]
        public event EventHandler CheckedChanged
        {
            add { Events.AddHandler(EventCheckedChanged, value); }
            remove { Events.RemoveHandler(EventCheckedChanged, value); }
        }

        #endregion

        #region 停用事件

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler PaddingChanged
        {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageChanged
        {
            add { base.BackgroundImageChanged += value; }
            remove { base.BackgroundImageChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BackgroundImageLayoutChanged
        {
            add { base.BackgroundImageLayoutChanged += value; }
            remove { base.BackgroundImageLayoutChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ForeColorChanged
        {
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler RightToLeftChanged
        {
            add { base.RightToLeftChanged += value; }
            remove { base.RightToLeftChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ImeModeChanged
        {
            add { base.ImeModeChanged += value; }
            remove { base.ImeModeChanged -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; }
            remove { base.MouseDoubleClick -= value; }
        }

        #endregion

        #region 新增属性

        private AnomalyButtonStylePattern stylePattern = AnomalyButtonStylePattern.Bezier;
        /// <summary>
        /// 自定义形状路径路径链接过渡模式
        /// </summary>
        [Description("自定义形状路径路径链接过渡模式")]
        [Category("杂项")]
        [PropertyOrder(-198)]
        [DefaultValue(AnomalyButtonStylePattern.Bezier)]
        public AnomalyButtonStylePattern StylePattern
        {
            get { return this.stylePattern; }
            set
            {
                if (this.stylePattern == value)
                    return;

                this.stylePattern = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private int borderThickness = 0;
        /// <summary>
        /// 边框厚度
        /// </summary>
        [Description("边框厚度")]
        [Category("杂项")]
        [PropertyOrder(-197)]
        [DefaultValue(0)]
        public int BorderThickness
        {
            get { return this.borderThickness; }
            set
            {
                if (this.borderThickness == value || value < 0)
                    return;

                this.borderThickness = value;
                this.Invalidate();
            }
        }

        private ShadowObject shadow;
        /// <summary>
        /// 阴影效果
        /// </summary>
        [Description("阴影效果")]
        [Category("杂项")]
        [PropertyOrder(-195)]
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ShadowObject Shadow
        {
            get
            {
                if (this.shadow == null)
                    this.shadow = new ShadowObject(this);
                return this.shadow;
            }
        }

        private HML.PointFR textLocation = new HML.PointFR(84, 75);
        /// <summary>
        /// 文本坐标位置
        /// </summary>
        [Description("文本坐标位置")]
        [Category("杂项")]
        [PropertyOrder(-193)]
        [DefaultValue(typeof(HML.PointFR), "84, 75")]
        [Editor(typeof(AnomalyButtonTextLocationEditor), typeof(UITypeEditor))]
        public HML.PointFR TextLocation
        {
            get { return this.textLocation; }
            set
            {
                if (this.textLocation == value)
                    return;

                this.textLocation = value;
                this.Invalidate();
            }
        }

        private string shapePoints = "";
        /// <summary>
        /// 自定义形状坐标集合（不包含系统缩放比例）,  格式： {x,y}{x,y}....{x,y}
        /// </summary>
        [Description("自定义形状坐标集合（不包含系统缩放比例）,  格式： {x,y}{x,y}....{x,y}")]
        [Category("杂项")]
        [PropertyOrder(-191)]
        [DefaultValue("")]
        [Bindable(true)]
        [Editor(typeof(MultilineStringEditor), typeof(UITypeEditor))]
        public string ShapePoints
        {
            get { return this.shapePoints; }
            set
            {
                if (this.shapePoints == value)
                    return;

                this.shapePoints = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private bool checkButton = false;
        /// <summary>
        /// 是否为开启checkButton功能
        /// </summary>
        [Description("是否为开启checkButton功能")]
        [Category("杂项")]
        [PropertyOrder(-188)]
        [DefaultValue(false)]
        public bool CheckButton
        {
            get { return this.checkButton; }
            set
            {
                if (this.checkButton == value)
                    return;

                this.checkButton = value;
                this.Invalidate();
            }
        }

        private bool autoCheck = true;
        /// <summary>
        /// 单击时是否自动更改控件状态
        /// </summary>
        [Description("单击时是否自动更改控件状态")]
        [Category("杂项")]
        [PropertyOrder(-186)]
        [DefaultValue(true)]
        public bool AutoCheck
        {
            get { return this.autoCheck; }
            set
            {
                if (this.autoCheck == value)
                    return;

                this.autoCheck = value;
            }
        }

        private bool _checked = false;
        /// <summary>
        /// 控件是否选中
        /// </summary>
        [DefaultValue(false)]
        [Description("控件是否选中")]
        [Category("杂项")]
        [PropertyOrder(-184)]
        public bool Checked
        {
            get { return this._checked; }
            set
            {
                if (this._checked == value)
                    return;

                this._checked = value;
                this.Invalidate();

                this.OnCheckedChanged(EventArgs.Empty);
            }
        }

        /// <summary>
        /// 鼠标是否已进入
        /// </summary>
        [Browsable(false)]
        public bool IsMouseEnter
        {
            get { return this.mouseenterobject == this; }
        }

        private bool shapeEditorEnabled = true;
        /// <summary>
        /// 启用自定义形状编辑功能
        /// </summary>
        [Description("启用自定义形状编辑功能")]
        [Category("VS视图设计器功能")]
        [AnomalyButtonDesignerPropertyAttribute]
        [PropertyOrder(-102)]
        [DefaultValue(true)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShapeEditorEnabled
        {
            get { return this.shapeEditorEnabled; }
            set
            {
                if (this.shapeEditorEnabled == value)
                    return;

                this.shapeEditorEnabled = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        /// <summary>
        /// 自定义形状布局整体调整： 1.单击 四周按钮停靠路径位置。 2. 拖动 中间按钮修改路径位置。
        /// </summary>
        [Description("自定义形状布局调整： 1.单击 四周按钮停靠路径位置。 2. 拖动 中间按钮修改路径位置。")]
        [Category("VS视图设计器功能")]
        [AnomalyButtonDesignerPropertyAttribute]
        [PropertyOrder(-100)]
        [DefaultValue(null)]
        [Editor(typeof(AnomalyButtonShapePointsEditor), typeof(UITypeEditor))]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public object ShapeLocationAnchor
        {
            get
            {
                return null;
            }
            set
            {

            }
        }

        private Color shapePathLineColor = Color.White;
        /// <summary>
        /// 自定义形状编辑路径颜色
        /// </summary>
        [Description("自定义形状编辑路径颜色")]
        [Category("VS视图设计器功能")]
        [AnomalyButtonDesignerPropertyAttribute]
        [PropertyOrder(-98)]
        [DefaultValue(typeof(Color), "White")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public Color ShapePathLineColor
        {
            get { return this.shapePathLineColor; }
            set
            {
                if (this.shapePathLineColor == value)
                    return;
                this.shapePathLineColor = value;

                if (this.DesignMode)
                {
                    this.Invalidate();
                }
            }
        }

        private int shapePathPointRadius = 4;
        /// <summary>
        /// 自定义形状编辑点半径
        /// </summary>
        [Description("自定义形状编辑点半径")]
        [Category("VS视图设计器功能")]
        [AnomalyButtonDesignerPropertyAttribute]
        [PropertyOrder(-96)]
        [DefaultValue(4)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public int ShapePathPointRadius
        {
            get
            {
                return this.shapePathPointRadius;
            }
            set
            {
                if (this.shapePathPointRadius == value || value <= 0)
                    return;

                this.shapePathPointRadius = value;
                this.InitializeElement();
                this.Invalidate();
            }
        }

        private Color shapePathPointNormalColor = Color.White;
        /// <summary>
        /// 自定义形状编辑点背景颜色(正常)
        /// </summary>
        [Description("自定义形状编辑点背景颜色(正常)")]
        [Category("VS视图设计器功能")]
        [AnomalyButtonDesignerPropertyAttribute]
        [PropertyOrder(-94)]
        [DefaultValue(typeof(Color), "White")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public Color ShapePathPointNormalColor
        {
            get { return this.shapePathPointNormalColor; }
            set
            {
                if (this.shapePathPointNormalColor == value)
                    return;

                this.shapePathPointNormalColor = value;
                if (this.DesignMode && this.ShapeEditorEnabled)
                {
                    this.Invalidate();
                }
            }
        }

        private Color shapePathPointEnterColor = Color.Aqua;
        /// <summary>
        /// 自定义形状编辑点背景颜色(鼠标进入)
        /// </summary>
        [Description("自定义形状编辑点背景颜色(鼠标进入)")]
        [Category("VS视图设计器功能")]
        [AnomalyButtonDesignerPropertyAttribute]
        [PropertyOrder(-92)]
        [DefaultValue(typeof(Color), "Aqua")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public Color ShapePathPointEnterColor
        {
            get { return this.shapePathPointEnterColor; }
            set
            {
                if (this.shapePathPointEnterColor == value)
                    return;

                this.shapePathPointEnterColor = value;
                if (this.DesignMode && this.ShapeEditorEnabled)
                {
                    this.Invalidate();
                }
            }
        }

        private bool shapePathPointTipEnable = true;
        /// <summary>
        /// 启用自定义形状编辑点提示
        /// </summary>
        [Description("启用自定义形状编辑点提示")]
        [Category("VS视图设计器功能")]
        [AnomalyButtonDesignerPropertyAttribute]
        [PropertyOrder(-90)]
        [DefaultValue(true)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public bool ShapePathPointTipEnable
        {
            get { return this.shapePathPointTipEnable; }
            set
            {
                if (this.shapePathPointTipEnable == value)
                    return;

                this.shapePathPointTipEnable = value;
                this.Invalidate();
            }
        }

        private Color shapePathPointTipColor = Color.DarkGreen;
        /// <summary>
        /// 自定义形状编辑路径文本颜色
        /// </summary>
        [Description("自定义形状编辑路径颜色")]
        [Category("VS视图设计器功能")]
        [AnomalyButtonDesignerPropertyAttribute]
        [PropertyOrder(-86)]
        [DefaultValue(typeof(Color), "DarkGreen")]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public Color ShapePathPointTipColor
        {
            get { return this.shapePathPointTipColor; }
            set
            {
                if (this.shapePathPointTipColor == value)
                    return;
                this.shapePathPointTipColor = value;

                if (this.DesignMode && this.ShapeEditorEnabled)
                {
                    this.Invalidate();
                }
            }
        }

        #endregion

        #region 重写属性

        protected override Size DefaultSize
        {
            get { return new Size(200, 120); }
        }

        protected override ImeMode DefaultImeMode
        {
            get { return ImeMode.Disable; }
        }

        #endregion

        #region 停用属性

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Padding Padding
        {
            get { return base.Padding; }
            set { base.Padding = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new Image BackgroundImage
        {
            get { return base.BackgroundImage; }
            set { base.BackgroundImage = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImageLayout BackgroundImageLayout
        {
            get { return base.BackgroundImageLayout; }
            set { base.BackgroundImageLayout = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override RightToLeft RightToLeft
        {
            get { return base.RightToLeft; }
            set { base.RightToLeft = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public new ImeMode ImeMode
        {
            get { return base.ImeMode; }
            set { base.ImeMode = value; }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new Color BackColor
        {
            get { return this.Checked ? this.StyleAppearance.Checked.Normal.BackColor : this.StyleAppearance.UnChecked.Normal.BackColor; }
            set { }
        }

        [Browsable(false)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public override Color ForeColor
        {
            get { return this.Checked ? this.StyleAppearance.Checked.Normal.TextColor : this.StyleAppearance.UnChecked.Normal.TextColor; }
            set { }
        }

        #endregion

        #region 字段

        /// <summary>
        /// 鼠标按下类型
        /// </summary>
        private MouseButtons mousedowntype = MouseButtons.None;
        /// <summary>
        /// 鼠标已进入对象
        /// </summary>
        private object mouseenterobject = null;

        #endregion

        public AnomalyButton()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.StandardClick, false);//自定义单击事件逻辑
            SetStyle(ControlStyles.StandardDoubleClick, false);//停用双加事件

            this.InitializeElement();
            this.OnSkinChanged();
        }

        #region 重写

        protected override void OnScaleDpiChangedInitialize()
        {
            this.InitializeElement();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;

            Color border_color = Color.Empty;
            Color back_color = Color.Empty;
            Color fore_color = Color.Empty;
            Color gradual_color = Color.Empty;

            StyleAppearanceObject.StateAppearanceObject stateAppearance = (this.CheckButton && this.Checked) ? this.StyleAppearance.Checked : this.StyleAppearance.UnChecked;
            if (!this.Enabled)
            {
                border_color = stateAppearance.Disabled.BorderColor;
                back_color = stateAppearance.Disabled.BackColor;
                fore_color = stateAppearance.Disabled.TextColor;
                gradual_color = stateAppearance.Disabled.ShadowColor;
            }
            else if (this.IsMouseEnter)
            {
                border_color = stateAppearance.Enter.BorderColor;
                back_color = stateAppearance.Enter.BackColor;
                fore_color = stateAppearance.Enter.TextColor;
                gradual_color = stateAppearance.Enter.ShadowColor;
            }
            else
            {
                border_color = stateAppearance.Normal.BorderColor;
                back_color = stateAppearance.Normal.BackColor;
                fore_color = stateAppearance.Normal.TextColor;
                gradual_color = stateAppearance.Normal.ShadowColor;
            }

            // 绘制背景
            PointF[] pointsArr = AnomalyButton.UnScaleStrConvertToScaleArr(this.ShapePoints, this.ScaleDpi);

            SolidBrush back_sb = new SolidBrush(back_color);
            if ((this.DesignMode == false && pointsArr.Length >= 3) || (this.DesignMode == true && this.ShapeEditorEnabled == false && pointsArr.Length >= 3))
            {
                GraphicsPath back_gp = new GraphicsPath();
                if (this.StylePattern == AnomalyButtonStylePattern.Bezier)
                {
                    back_gp.AddClosedCurve(pointsArr);
                }
                else
                {
                    back_gp.AddPolygon(pointsArr);
                }

                for (int i = 0; i < pointsArr.Length; i++)
                {
                    if (!back_gp.IsVisible(pointsArr[i].X - 1, pointsArr[i].Y))
                    {
                        pointsArr[i].X += 1;
                    }
                    else if (!back_gp.IsVisible(pointsArr[i].X + 1, pointsArr[i].Y))
                    {
                        pointsArr[i].X -= 1;
                    }

                    if (!back_gp.IsVisible(pointsArr[i].X, pointsArr[i].Y - 1))
                    {
                        pointsArr[i].Y += 1;
                    }
                    else if (!back_gp.IsVisible(pointsArr[i].X, pointsArr[i].Y + 1))
                    {
                        pointsArr[i].Y -= 1;
                    }
                }

                if (this.StylePattern == AnomalyButtonStylePattern.Bezier)
                {
                    g.FillClosedCurve(back_sb, pointsArr);
                }
                else
                {
                    g.FillPolygon(back_sb, pointsArr);
                }
                back_gp.Dispose();
            }
            else
            {
                g.FillRectangle(back_sb, this.ClientRectangle);
            }
            back_sb.Dispose();

            //阴影
            if (this.Shadow.Enabled)
            {
                float scale_radius = this.Shadow.Radius * this.ScaleDpi;

                HML.PointFR gradient_center_point = new HML.PointFR(this.Shadow.Location.X * this.ScaleDpi, this.Shadow.Location.Y * this.ScaleDpi);
                GraphicsPath back_gradual_gp = new GraphicsPath();
                RectangleF back_gradual_rect = new RectangleF(gradient_center_point.X - scale_radius, gradient_center_point.Y - scale_radius, scale_radius * 2, scale_radius * 2);
                back_gradual_gp.AddEllipse(back_gradual_rect);
                PathGradientBrush back_gradual_gpb = new PathGradientBrush(back_gradual_gp);
                back_gradual_gpb.CenterPoint = gradient_center_point.ConvertTo();
                back_gradual_gpb.CenterColor = gradual_color;
                back_gradual_gpb.SurroundColors = new Color[] { Color.Transparent };
                g.FillEllipse(back_gradual_gpb, back_gradual_rect);
                back_gradual_gpb.Dispose();
                back_gradual_gp.Dispose();
            }

            // 文本
            if (!String.IsNullOrWhiteSpace(this.Text))
            {
                SolidBrush text_sb = new SolidBrush(fore_color);
                Size text_size = Size.Ceiling(g.MeasureString(this.Text, this.Font, int.MaxValue, StringFormat.GenericDefault));
                g.DrawString(this.Text, this.Font, text_sb, new PointF(TextLocation.X * this.ScaleDpi - text_size.Width / 2f, TextLocation.Y * this.ScaleDpi - text_size.Height / 2f));
                text_sb.Dispose();
            }

            //边框
            if (!this.DesignMode && this.BorderThickness > 0)
            {

                Pen border_pen = new Pen(border_color, this.BorderThickness) { Alignment = PenAlignment.Inset };
                if ((this.DesignMode == false && pointsArr.Length >= 3) || (this.DesignMode == true && this.ShapeEditorEnabled == false && pointsArr.Length >= 3))
                {
                    if (this.StylePattern == AnomalyButtonStylePattern.Bezier)
                    {
                        g.DrawClosedCurve(border_pen, pointsArr);
                    }
                    else
                    {
                        g.DrawPolygon(border_pen, pointsArr);
                    }
                }
                else
                {
                    g.DrawRectangle(border_pen, this.ClientRectangle.X, this.ClientRectangle.Y, this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);
                }
                border_pen.Dispose();
            }

            //控件激活状态虚线框
            if (this.Focused && this.ShowFocusCues)
            {
                g.SmoothingMode = SmoothingMode.Default;
                Pen border_pen = new Pen(this.StyleAppearance.ActivateColor) { DashStyle = DashStyle.Dot, Alignment = PenAlignment.Inset };
                if ((this.DesignMode == false && pointsArr.Length >= 3) || (this.DesignMode == true && this.ShapeEditorEnabled == false && pointsArr.Length >= 3))
                {
                    if (this.StylePattern == AnomalyButtonStylePattern.Bezier)
                    {
                        g.DrawClosedCurve(border_pen, pointsArr);
                    }
                    else
                    {
                        g.DrawPolygon(border_pen, pointsArr);
                    }
                }
                else
                {
                    g.DrawRectangle(border_pen, this.ClientRectangle.X + 2, this.ClientRectangle.Y + 2, this.ClientRectangle.Width - 5, this.ClientRectangle.Height - 5);
                }
                border_pen.Dispose();
            }

            base.OnPaint(e);

        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);

            this.Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);

            this.mousedowntype = MouseButtons.None;
            this.Invalidate();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            base.OnEnabledChanged(e);

            if (!this.Enabled)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);

            if (!this.Visible)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnParentChanged(EventArgs e)
        {
            base.OnParentChanged(e);

            if (this.Parent == null)
            {
                this.mousedowntype = MouseButtons.None;
                this.mouseenterobject = null;
                this.Invalidate();
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);

            this.mouseenterobject = this;
            this.Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            this.mouseenterobject = null;
            this.Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (!this.Focused)
            {
                this.Focus();
            }

            this.mousedowntype |= e.Button;

            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (this.mousedowntype.HasFlag(MouseButtons.Left) && this.Region.IsVisible(e.Location))
                {
                    this.OnClick(e);
                    this.OnMouseClick(e);
                    if (this.CheckButton && this.AutoCheck)
                    {
                        this.Checked = !this.Checked;
                    }
                }
            }
            this.mousedowntype &= ~e.Button;

            base.OnMouseUp(e);
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            switch (e.KeyData)
            {
                case Keys.Space:
                    {
                        this.OnClick(EventArgs.Empty);
                        break;
                    }
            }

            base.OnKeyUp(e);
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);

            this.InitializeElement();
            this.Invalidate();
        }

        #endregion

        #region 虚方法

        protected virtual void OnCheckedChanged(EventArgs e)
        {
            EventHandler handler = Events[EventCheckedChanged] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// [不包含系统缩放比例坐标字符串] 转换成 [包含系统缩放比例坐标对象]
        /// </summary>
        /// <param name="unScaleStr">不包含系统缩放比例坐标字符串</param>
        /// <param name="dpi">缩放比例</param>
        /// <returns>包含系统缩放比例坐标对象</returns>
        public static PointF[] UnScaleStrConvertToScaleArr(string unScaleStr, float dpi)
        {
            string[] pointsStrArr = unScaleStr.Replace(Environment.NewLine, "").Replace(" ", "").Split(new char[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
            PointF[] pointsArr = new PointF[pointsStrArr.Length];
            for (int i = 0; i < pointsStrArr.Length; i++)
            {
                string[] xyArr = pointsStrArr[i].Split(',');
                float xy_x = 0;
                float xy_y = 0;
                if (xyArr.Length > 0)
                {
                    float.TryParse(xyArr[0], out xy_x);
                }
                if (xyArr.Length > 1)
                {
                    float.TryParse(xyArr[1], out xy_y);
                }
                pointsArr[i] = new PointF((float)Math.Round(xy_x * dpi, 2), (float)Math.Round(xy_y * dpi, 2));
            }
            return pointsArr;
        }

        /// <summary>
        /// [不包含系统缩放比例坐标字符串] 转换成 [不包含系统缩放比例坐标对象]
        /// </summary>
        /// <param name="unScaleStr">不包含系统缩放比例坐标字符串</param>
        /// <returns>不包含系统缩放比例坐标对象</returns>
        public static PointF[] UnScaleStrConvertToUnScaleArr(string unScaleStr)
        {
            string[] pointsStrArr = unScaleStr.Replace(Environment.NewLine, "").Replace(" ", "").Split(new char[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries);
            PointF[] pointsArr = new PointF[pointsStrArr.Length];
            for (int i = 0; i < pointsStrArr.Length; i++)
            {
                string[] xyArr = pointsStrArr[i].Split(',');
                float xy_x = 0;
                float xy_y = 0;
                if (xyArr.Length > 0)
                {
                    float.TryParse(xyArr[0], out xy_x);
                }
                if (xyArr.Length > 1)
                {
                    float.TryParse(xyArr[1], out xy_y);
                }
                pointsArr[i] = new PointF((float)Math.Round(xy_x, 2), (float)Math.Round(xy_y, 2));
            }
            return pointsArr;
        }

        /// <summary>
        /// [包含系统缩放比例坐标对象] 转换成 [不包含系统缩放比例坐标字符串]
        /// </summary>
        /// <param name="scaleArr">包含系统缩放比例坐标对象</param>
        /// <param name="dpi">缩放比例</param>
        /// <returns>包含系统缩放比例坐标字符串</returns>
        public static string ScaleArrConvertToUnScaleStr(PointF[] scaleArr, float dpi)
        {
            List<string> pointList = new List<string>();
            for (int i = 0; i < scaleArr.Length; i++)
            {
                pointList.Add("{" + Math.Round(scaleArr[i].X / dpi, 2) + "," + Math.Round(scaleArr[i].Y / dpi, 2) + "}");
            }
            return String.Join(" ", pointList);
        }

        /// <summary>
        /// [不包含系统缩放比例坐标对象] 转换成 [不包含系统缩放比例坐标字符串]
        /// </summary>
        /// <param name="unScaleArr">不包含系统缩放比例坐标对象</param>
        /// <returns>不包含系统缩放比例坐标字符串</returns>
        public static string UnScaleArrConvertToUnScaleStr(PointF[] unScaleArr)
        {
            List<string> pointList = new List<string>();
            for (int i = 0; i < unScaleArr.Length; i++)
            {
                pointList.Add("{" + unScaleArr[i].X + "," + unScaleArr[i].Y + "}");
            }
            return String.Join(" ", pointList);
        }

        #endregion

        #region 公开方法

        /// <summary>
        /// 初始化控件内部元素布局
        /// </summary>
        public void InitializeElement()
        {
            PointF[] pointsArr = AnomalyButton.UnScaleStrConvertToScaleArr(this.ShapePoints, this.ScaleDpi);
            if ((this.DesignMode == false && pointsArr.Length >= 3) || (this.DesignMode == true && this.ShapeEditorEnabled == false && pointsArr.Length >= 3))
            {
                GraphicsPath shape_gp = new GraphicsPath();
                if (this.StylePattern == AnomalyButtonStylePattern.Bezier)
                {
                    shape_gp.AddClosedCurve(pointsArr);
                }
                else
                {
                    shape_gp.AddPolygon(pointsArr);
                }
                this.Region = new Region(shape_gp);
                shape_gp.Dispose();
            }
            else
            {
                GraphicsPath shape_gp = new GraphicsPath();
                shape_gp.AddRectangle(this.ClientRectangle);
                this.Region = new Region(shape_gp);
                shape_gp.Dispose();
            }

        }

        #endregion

        #region 类

        [TypeConverter(typeof(PropertyOrderConverter))]
        public class ShadowObject
        {
            private AnomalyButton owner = null;
            internal ShadowObject(AnomalyButton owner) { this.owner = owner; }

            #region 属性

            private bool enabled = false;
            /// <summary>
            /// 是否启用阴影效果
            /// </summary>
            [Description("是否启用阴影效果")]
            [PropertyOrder(-120)]
            [DefaultValue(false)]
            public bool Enabled
            {
                get { return this.enabled; }
                set
                {
                    if (this.enabled == value)
                        return;

                    this.enabled = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            private int radius = 70;
            /// <summary>
            /// 阴影效果半径
            /// </summary>
            [Description("阴影效果半径")]
            [PropertyOrder(-118)]
            [DefaultValue(70)]
            [Editor(typeof(AnomalyButtonShadowRadiusEditor), typeof(UITypeEditor))]
            public int Radius
            {
                get { return this.radius; }
                set
                {
                    if (this.radius == value || value <= 0)
                        return;

                    this.radius = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            private HML.PointFR location = new HML.PointFR(50, 40);
            /// <summary>
            /// 阴影效果坐标位置
            /// </summary>
            [Description("阴影效果坐标位置")]
            [PropertyOrder(-116)]
            [DefaultValue(typeof(HML.PointFR), "50, 40")]
            [Editor(typeof(AnomalyButtonShadowLocationEditor), typeof(UITypeEditor))]
            public HML.PointFR Location
            {
                get { return this.location; }
                set
                {
                    if (this.location == value)
                        return;

                    this.location = value;
                    if (this.owner != null)
                    {
                        this.owner.Invalidate();
                    }
                }
            }

            #endregion

        }

        #endregion 

        #region 外观

        public class StyleAppearanceObject : AppearanceObjectBase
        {
            internal StyleAppearanceObject(ISkinObject owner, AppearanceObjectBase parent) : base(owner, parent) { }

            #region 属性

            private Color skinActivateColor = Color.Empty;
            private readonly Color defaultActivateColor = SystemColors.Window;
            private Color activateColor = Color.Empty;
            /// <summary>
            /// 控件激活的虚线框颜色
            /// </summary>
            [Description("控件激活的虚线框颜色")]
            [PropertyOrder(-200)]
            [SkinProperty(true, false)]
            public Color ActivateColor
            {
                get
                {
                    if (this.owner.GetSkinObjectSkinStateCore())
                    {
                        return this.skinActivateColor;
                    }

                    if (this.activateColor != Color.Empty)
                    {
                        return this.activateColor;
                    }

                    return this.defaultActivateColor;
                }
                set
                {
                    if (this.activateColor == value)
                        return;

                    this.activateColor = value;
                    this.Invalidate();
                }
            }
            private bool ShouldSerializeActivateColor()
            {
                return this.activateColor != Color.Empty;
            }
            private void ResetActivateColor()
            {
                this.activateColor = Color.Empty;
                this.Invalidate();
            }

            private StateAppearanceObject unChecked;

            /// <summary>
            /// 未选中状态外观
            /// </summary>
            [Description("未选中状态外观")]
            [PropertyOrder(-199)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public StateAppearanceObject UnChecked
            {
                get
                {
                    if (this.unChecked == null)
                        this.unChecked = new StateAppearanceObject(this.owner, this
                            , SystemColors.ActiveCaption
                            , SystemColors.GradientActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.GradientInactiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.GradientActiveCaption
                            , SystemColors.InactiveCaption
                            , SystemColors.InactiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.InactiveBorder
                            );
                    return this.unChecked;
                }
            }

            private StateAppearanceObject _checked;
            /// <summary>
            /// 已选中状态外观
            /// </summary>
            [Description("已选中状态外观")]
            [PropertyOrder(-192)]
            [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
            [SkinProperty(true, false)]
            public StateAppearanceObject Checked
            {
                get
                {
                    if (this._checked == null)
                        this._checked = new StateAppearanceObject(this.owner, this
                            , SystemColors.ActiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.GradientActiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.GradientActiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.GradientInactiveCaption
                            , SystemColors.ActiveCaption
                            , SystemColors.InactiveCaption
                            , SystemColors.ButtonHighlight
                            , SystemColors.InactiveBorder
                          );
                    return this._checked;
                }
            }

            #endregion

            public class StateAppearanceObject : AppearanceObjectBase
            {
                internal StateAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderNormalColor, Color backNormalColor, Color textNormalColor, Color shadowNormalColor, Color borderEnterColor, Color backEnterColor, Color textEnterColor, Color shadowEnterColor, Color borderDisabledColor, Color backDisabledColor, Color textDisabledColor, Color shadowDisabledColor) : base(owner, parent)
                {
                    this.borderNormalColor = borderNormalColor;
                    this.backNormalColor = backNormalColor;
                    this.textNormalColor = textNormalColor;
                    this.shadowNormalColor = shadowNormalColor;
                    this.borderEnterColor = borderEnterColor;
                    this.backEnterColor = backEnterColor;
                    this.textEnterColor = textEnterColor;
                    this.shadowEnterColor = shadowEnterColor;
                    this.borderDisabledColor = borderDisabledColor;
                    this.backDisabledColor = backDisabledColor;
                    this.textDisabledColor = textDisabledColor;
                    this.shadowDisabledColor = shadowDisabledColor;
                }

                #region 属性

                private Color borderNormalColor = Color.Empty;
                private Color backNormalColor = Color.Empty;
                private Color textNormalColor = Color.Empty;
                private Color shadowNormalColor = Color.Empty;
                private ItemAppearanceObject normal;
                /// <summary>
                /// 正常状态
                /// </summary>
                [Description("正常状态")]
                [PropertyOrder(-194)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Normal
                {
                    get
                    {
                        if (this.normal == null)
                            this.normal = new ItemAppearanceObject(this.owner, this, this.borderNormalColor, this.backNormalColor, this.textNormalColor, this.shadowNormalColor);
                        return this.normal;
                    }
                }

                private Color borderEnterColor = Color.Empty;
                private Color backEnterColor = Color.Empty;
                private Color textEnterColor = Color.Empty;
                private Color shadowEnterColor = Color.Empty;
                private ItemAppearanceObject enter;
                /// <summary>
                /// 鼠标进入状态
                /// </summary>
                [Description("鼠标进入状态")]
                [PropertyOrder(-192)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Enter
                {
                    get
                    {
                        if (this.enter == null)
                            this.enter = new ItemAppearanceObject(this.owner, this, this.borderEnterColor, this.backEnterColor, this.textEnterColor, this.shadowEnterColor);
                        return this.enter;
                    }
                }

                private Color borderDisabledColor = Color.Empty;
                private Color backDisabledColor = Color.Empty;
                private Color textDisabledColor = Color.Empty;
                private Color shadowDisabledColor = Color.Empty;
                private ItemAppearanceObject disabled;
                /// <summary>
                /// 禁用状态
                /// </summary>
                [Description("禁用状态")]
                [PropertyOrder(-190)]
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
                [SkinProperty(true, false)]
                public ItemAppearanceObject Disabled
                {
                    get
                    {
                        if (this.disabled == null)
                            this.disabled = new ItemAppearanceObject(this.owner, this, this.borderDisabledColor, this.backDisabledColor, this.textDisabledColor, this.shadowDisabledColor);
                        return this.disabled;
                    }
                }

                #endregion

                public class ItemAppearanceObject : AppearanceObjectBase
                {
                    internal ItemAppearanceObject(ISkinObject owner, AppearanceObjectBase parent, Color borderColor, Color backColor, Color textColor, Color gradualColor) : base(owner, parent)
                    {
                        this.defaultBorderColor = borderColor;
                        this.defaultBackColor = backColor;
                        this.defaultTextColor = textColor;
                        this.defaultShadowColor = gradualColor;
                    }

                    #region 属性

                    private Color skinBorderColor = Color.Empty;
                    private readonly Color defaultBorderColor = Color.Empty;
                    private Color borderColor = Color.Empty;
                    /// <summary>
                    /// 边框颜色
                    /// </summary>
                    [Description("边框颜色")]
                    [PropertyOrder(-159)]
                    [SkinProperty(true, false)]
                    public Color BorderColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinBorderColor;
                            }

                            if (this.borderColor != Color.Empty)
                            {
                                return this.borderColor;
                            }

                            return this.defaultBorderColor;
                        }
                        set
                        {
                            if (this.borderColor == value)
                                return;

                            this.borderColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeBorderColor()
                    {
                        return this.borderColor != Color.Empty;
                    }
                    private void ResetBorderColor()
                    {
                        this.borderColor = Color.Empty;
                        this.Invalidate();
                    }

                    private Color skinBackColor = Color.Empty;
                    private readonly Color defaultBackColor = Color.Empty;
                    private Color backColor = Color.Empty;
                    /// <summary>
                    /// 背景颜色
                    /// </summary>
                    [Description("背景颜色")]
                    [PropertyOrder(-158)]
                    [SkinProperty(true, false)]
                    public Color BackColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinBackColor;
                            }

                            if (this.backColor != Color.Empty)
                            {
                                return this.backColor;
                            }

                            return this.defaultBackColor;
                        }
                        set
                        {
                            if (this.backColor == value)
                                return;

                            this.backColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeBackColor()
                    {
                        return this.backColor != Color.Empty;
                    }
                    private void ResetBackColor()
                    {
                        this.backColor = Color.Empty;
                        this.Invalidate();
                    }

                    private Color skinTextColor = Color.Empty;
                    private readonly Color defaultTextColor = Color.Empty;
                    private Color textColor = Color.Empty;
                    /// <summary>
                    /// 文本颜色
                    /// </summary>
                    [Description("文本颜色")]
                    [PropertyOrder(-157)]
                    [SkinProperty(true, false)]
                    public Color TextColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinTextColor;
                            }

                            if (this.textColor != Color.Empty)
                            {
                                return this.textColor;
                            }

                            return this.defaultTextColor;
                        }
                        set
                        {
                            if (this.textColor == value)
                                return;

                            this.textColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeTextColor()
                    {
                        return this.textColor != Color.Empty;
                    }
                    private void ResetTextColor()
                    {
                        this.textColor = Color.Empty;
                        this.Invalidate();
                    }

                    private Color skinShadowColor = Color.Empty;
                    private readonly Color defaultShadowColor = Color.Empty;
                    private Color shadowColor = Color.Empty;
                    /// <summary>
                    /// 阴影颜色
                    /// </summary>
                    [Description("阴影颜色")]
                    [PropertyOrder(-155)]
                    [Editor(typeof(AlphaColorEditor), typeof(UITypeEditor))]
                    [SkinProperty(true, false)]
                    public Color ShadowColor
                    {
                        get
                        {
                            if (this.owner.GetSkinObjectSkinStateCore())
                            {
                                return this.skinShadowColor;
                            }

                            if (this.shadowColor != Color.Empty)
                            {
                                return this.shadowColor;
                            }

                            return this.defaultShadowColor;
                        }
                        set
                        {
                            if (this.shadowColor == value)
                                return;

                            this.shadowColor = value;
                            this.Invalidate();
                        }
                    }
                    private bool ShouldSerializeShadowColor()
                    {
                        return this.shadowColor != Color.Empty;
                    }
                    private void ResetShadowColor()
                    {
                        this.shadowColor = Color.Empty;
                        this.Invalidate();
                    }

                    #endregion

                }

            }

        }

        #endregion

    }

}
